#pragma once

#include "raster.h"
#include "bitmap.h"
#include <xtd/type_traits.h>

namespace img {

/// makes from any bitmap raster with elements of arbitrary type and
/// two values: one for mask's 0, and another for mask's 1
template <class T> 
class dichromatic_raster {
public:
	typedef T elem_type;
	typedef typename xtd::type_traits<elem_type>::real_type real_elem_type;
	typedef const_raster_iterator<dichromatic_raster<T>, T const &> const_iterator;
public:
	bitmap const & _bitmap;
	T const _val0, _val1;
public:
	dichromatic_raster(bitmap const & bitmap, T const & val0, T const & val1) 
		: _bitmap(bitmap), _val0(val0), _val1(val1) { }
	size_type width() const 
		{ return _bitmap.width(); }
	size_type height() const
		{ return _bitmap.height(); }
	size_extent dim() const
		{ return _bitmap.dim(); }
	bool empty() const
		{ return _bitmap.empty(); }
	elem_type const & operator () (size_type x, size_type y) const
		{ return _bitmap(x, y) ? _val1 : _val0; }
	elem_type const & operator [] (point<size_type> p) const 
		{ return operator()(p.x, p.y); }
	elem_type const &  operator [] (point<int> p) const
		{ return operator()(p.x, p.y); }
	real_elem_type operator () (float x, float y) const
		{ return interpolate(* this, x, y); }
	real_elem_type operator [] (point<float> p) const
		{ return interpolate(* this, p.x, p.y); }
	const_iterator begin() const
		{ return const_iterator(* this, 0, 0); }
	const_iterator end() const
		{ return const_iterator(* this, 0, height()); }
};

template <class T> 
inline dichromatic_raster<T> make_dichromatic_raster(bitmap const & bitmap, T const & val0, T const & val1) 
	{ return dichromatic_raster<T>(bitmap, val0, val1); }

} //namespace img
